/***************************************************************************
 *   Copyright (C) 2009 by Kbranch                                         *
 *   kbranch@kbranch.net                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "common.h"
#include <fstream>
#include <iostream>
#include <string.h>

using namespace std;

// Initializes attack and buff values
void Init()
{
	numActiveBuffs = 0;
	
	// Simulation settings
	latency = int(0.25 * PRECISION); // Connection latency / reaction time to simulate
	fightLength = 60*5 * PRECISION; // Length of an individual fight
	numFights = 1000; // Number of fights to simulate
	staticStats.SetBaseBossArmor(10643); // Unmodified armor of the target
	minRoarPoints = 3; // Minimum combo points required before Savage Roar will be considered - ignored if Savage Roar is down
	maxRoarClip = 5 * PRECISION; // Maximum time left on Savage Roar before it can be used
	trinket1Delay = 0; // Amount of time to delay the first trinket1 proc
	trinket2Delay = 0; // Amount of time to delay the first trinket2 proc
	mangleBot = 0; // Whether mangle is assumed to always be on the target
	bleedBot = 0; // Whether the target is assumed to always be bleeding
	useShred = 1; // Whether Shred should be used to generate combo points
	
	// Internal variables
	nextAttack.name = -1; // The attack that's queued up to be used next
	nextAttack.time = 0; // Time the next attack will be performed at
	critMod = 2; // Bonus used to calculate crit damage
	isBleeding = 0; // Whether the target currently has a bleed active
	lastGCDAttackTime = 0 - gcd; // The last time a GCD was triggered
	energy = 100; // Current energy
	lastEnergyTick = 0; // Last time a point of energy was gained
	comboPoints = 0; // Current number of combo points
	shredGlyphCounter = 0; // Number of shreds used on the current Rip
	omenActive = 0; // Whether Omen of Clarity is currently active
	currentTime = 0; // Current time in the current fight
	lowestBuffTime = fightLength; // The time the lowest buff will expire
	trinketOverlapTime = 0; // Amount of time both trinket procs are up at the same time
	
	// Character settings
	staticStats.SetStat(HASTERATING, 192); // Haste rating from gear
	staticStats.SetStat(ARPENRATING, 104); // Armor penetration rating from gear
	staticStats.SetStat(HITRATING, 226); // Hit rating from gear
	staticStats.SetStat(EXPERTISERATING, 82); // Expertise rating from gear
	staticStats.SetStat(CRITRATING, 620); // Crit rating from gear
	staticStats.SetStat(BASEAP, 1950 + 2085); // Attack power from gear, including feral AP granted by the weapon
	staticStats.SetStat(WEAPONAP, 2238); // Total amount of attack power on the weapon, including feral AP and normal AP, but not strength or agility
	staticStats.SetStat(BASEAGI, 1088); // Agility from gear
	staticStats.SetStat(BASESTR, 10); // Strength from gear
	
	race = ELF; // Character race - ELF or COW
	
	REDMeta = 1; // +3% crit damage meta gem
	
	ripGlyph = 1; // +4 seconds to Tip
	shredGlyph = 1; // +2 seconds to Rip per Shred, max 6 seconds
	roarGlyph = 1; // Savage Roar grants 3% more damage
	mangleGlyph = 0; // +6 seconds to Mangle
	
	twoT7 = 1; // +4 seconds to Rip
	fourT7 = 1; // -3 seconds from Tiger's Fury cooldown
	twoT8 = 0; // Clearcast chance from bleeds
	fourT8 = 0; // +8 seconds to Savage Roar
	twoT9 = 0; // +3 seconds to Rake
	fourT9 = 0; // +5% crit to Rip and Ferocious Bite
	
	ripIdol = 1; // +21 Rip tick damage per combo point
	shredIdol = 0; // +203 damage to Shred
	mangleIdol = 0; // +153 agility for 12 seconds every mangle
	mutilationIdol = 0; // 70% chance of 200 agility after Mangle and Shred
	
	// Talents
	talents.ferocity = 5; // Reduces Mangle and Rake energy cost by 1 per point (0-5)
	talents.feralAggression = 0; // Increases Ferocious Bite damage by 3% per point (0-5)
	talents.savageFury = 2; // Increases Mangle and Rake damage by 10% per point (0-2)
	talents.feralInstinct = 3; // Increases swipe damage by 5% per point - currently not used (0-3)
	talents.sharpenedClaws = 3; // Increases crit chance by 2% per point (0-3)
	talents.primalFury = 2; // 50% chance to generate an extra combo point on crits per talent point - currently either 0% or 100% chance.  One point does nothing.(0-2)
	talents.primalPrecision = 2; // Increases expertise by 5 and reduces energy lost on finisher misses by 40% per point (0-2)
	talents.predatoryStrikes = 3; // Increases attack power by 40 and weapon attack power by 7% (20% at max) per point (0-3)
	talents.shreddingAttacks = 2; // Reduces energy cost of Shred by 9 per point (0-2)
	talents.survivalOfTheFittest = 3; // Increases all stats by 2% per point (0-3)
	talents.heartOfTheWild = 5; // Increases attack power by 2% per point (0-5)
	talents.leaderOfThePack = 1; // Increases crit chance by 5% (0-1)
	talents.predatoryInstincts = 3; // Increases damage done by crits by 3% (10% at max) per point (0-3)
	talents.mangle = 1; // Deals damage and increases bleed damage by 30% for 12 seconds - currently not used, assumed to always be available (0-1) 
	talents.improvedMangle = 3; // Reduces energy cost of Mangle by 2 per point (0-3)
	talents.kingOfTheJungle = 3; // Causes Tiger's Fury to also grant 20 energy per point (0-3)
	talents.rendAndTear = 5; // Increases Shred damage on bleeding targets by 4% and increases Ferocious Bite crit chance by 5% per point (0-5)
	talents.primalGore = 1; // Allows Rip ticks to crit (0-1)
	talents.berserk = 1; // Reduces energy cost of all abilities by 50% for 15 seconds, 3 minute cooldown (0-1)
	
	talents.improvedMarkOfTheWild = 2; // Increases all stats by 1% per point (0-2)
	talents.naturalist = 5; // Increases physical damage by 2% per point (0-5)
	talents.omenOfClarity = 1; // Allows auto swings to have a chance to reduce the energy cost of the next attack by 100% (0-1)
	talents.masterShapeshifter = 2; // Increases crit chance by 2% per point (0-2)
	
	for(int i = 0; i < numAttacks; i++)
	{
		attacks[i].count = 0;
		attacks[i].damageDealt = 0;
		attacks[i].avgDamage = 0;
		attacks[i].avgTick = 0;
		attacks[i].extraEnergyDamage = 0;
		attacks[i].hits = 0;
		attacks[i].tickHits = 0;
		attacks[i].crits = 0;
		attacks[i].tickCrits = 0;
		attacks[i].glances = 0;
		attacks[i].misses = 0;
		attacks[i].isBleed = 0;
		attacks[i].cost = 0;
	}
	
	for(int i = 0; i < numBuffs; i++)
	{
		buffs[i].type = -1;
		buffs[i].enabled = 0;
		buffs[i].active = 0;
		buffs[i].trigger = -1;
		buffs[i].cooldown = 0;
		buffs[i].nextCooldown = 0;
		buffs[i].duration = 0;
		buffs[i].canTick = 0;
		buffs[i].lastTrigger = 0 - 10000 * PRECISION;
		buffs[i].endTime = -1;
		buffs[i].lastTick = 0;
		buffs[i].nextTick = 0;
		buffs[i].lastFaded = 0;
		buffs[i].tickFrequency = 0;
		buffs[i].downTime = 0;
		buffs[i].upTime = 0;
		buffs[i].timeLeft = 0;
		buffs[i].avgTick = 0;
		buffs[i].procChance = 0;
		activeBuffs[i] = -1;
	}
	
	buffs[SOE].enabled = 1;
	buffs[impSOE].enabled = 1;
	buffs[BOM].enabled = 1;
	buffs[impBOM].enabled = 1;
	buffs[TRUESHOT].enabled = 1;
	buffs[FI].enabled = 1;
	buffs[FFF_B].enabled = 1;
	buffs[SR].enabled = 1;
	buffs[WF].enabled = 1;
	buffs[impWF].enabled = 1;
	buffs[MOTW].enabled = 1;
	buffs[impMOTW].enabled = 1;
	buffs[BOK].enabled = 1;
	buffs[HP].enabled = 1;
	buffs[SUNDER].enabled = 1;
	buffs[HOC].enabled = 1;
	buffs[BF].enabled = 1;
	buffs[HEROISM].enabled = 1;
	
	LoadSettings();
	
	#ifdef DEBUG
	numFights = 1;
	#endif
	
	attacks[SHRED].cost = 60 - 9 * talents.shreddingAttacks;
	
	attacks[MANGLE_A].cost = 40 - 2 * talents.improvedMangle;
	
	attacks[RAKE_A].isBleed = 1;
	attacks[RAKE_A].cost = 40 - talents.ferocity;
	
	attacks[RIP_A].isBleed = 1;
	attacks[RIP_A].cost = 30;
	
	attacks[BITE].cost = 35;
	
	attacks[ROAR_A].cost = 25;
	
	attacks[BERSERK_A].cost = 0;
	
	buffs[RAKE_B].enabled = 1;
	buffs[RAKE_B].duration = (9 + twoT9 * 3) * PRECISION;
	buffs[RAKE_B].tickFrequency = 3 * PRECISION;
	buffs[RAKE_B].canTick = 1;
	
	buffs[RIP_B].enabled = 1;
	buffs[RIP_B].duration = (12 + ripGlyph * 4 + twoT7 * 4) * PRECISION;
	buffs[RIP_B].tickFrequency = 2 * PRECISION;
	buffs[RIP_B].canTick = 1;
	
	buffs[SOE].type = PASSIVE;
	buffs[SOE].stats.SetStat(BASESTR, 155);
	buffs[SOE].stats.SetStat(BASEAGI, 155);
	
	buffs[impSOE].type = PASSIVE;
	buffs[impSOE].stats.SetStat(BASESTR, 23);
	buffs[impSOE].stats.SetStat(BASEAGI, 23);
	
	buffs[MANGLE_B].type = USE;
	buffs[MANGLE_B].stats.SetModifier(BLEEDDAMAGEMOD, 1.30);
	buffs[MANGLE_B].duration = (12 + mangleGlyph * 6) * PRECISION;
	buffs[MANGLE_B].enabled = 1;
	
	if(mangleBot)
		buffs[MANGLE_B].duration = fightLength;
	
	buffs[BOM].type = PASSIVE;
	buffs[BOM].stats.SetStat(BASEAP, 550);
	
	buffs[impBOM].type = PASSIVE;
	buffs[impBOM].stats.SetStat(BASEAP, 137);
	
	buffs[TRUESHOT].type = PASSIVE;
	buffs[TRUESHOT].stats.SetModifier(APMOD, 1.10);
	
	buffs[ROAR_B].type = USE;
	buffs[ROAR_B].stats.SetModifier(DAMAGEMOD, 1.30 * (1 + 0.03 * roarGlyph));
	buffs[ROAR_B].enabled = 1;
	
	buffs[FURY_B].type = USE;
	buffs[FURY_B].stats.SetStat(WEAPONDAMAGE, 80);
	buffs[FURY_B].duration = 6 * PRECISION;
	buffs[FURY_B].cooldown = (30 - fourT7 * 3) * PRECISION;
	buffs[FURY_B].enabled = 1;
	
	buffs[FI].type = PASSIVE;
	buffs[FI].stats.SetModifier(DAMAGEMOD, 1.03);
	
	buffs[FFF_B].type = PASSIVE;
	buffs[FFF_B].stats.SetModifier(ARPENMOD, 0.95);
	buffs[FFF_B].duration = 300 * PRECISION;
	buffs[FFF_B].cooldown = 6 * PRECISION;
	
	buffs[SR].type = PASSIVE;
	buffs[SR].stats.SetModifier(HASTEMOD, 1.03);
	
	buffs[WF].type = PASSIVE;
	buffs[WF].stats.SetModifier(HASTEMOD, 1.16);
	
	buffs[impWF].type = PASSIVE;
	buffs[impWF].stats.SetModifier(HASTEMOD, 1.0345);
	
	buffs[MOTW].type = PASSIVE;
	buffs[MOTW].stats.SetStat(BASEAGI, 37);
	buffs[MOTW].stats.SetStat(BASESTR, 37);
	
	buffs[impMOTW].type = PASSIVE;
	buffs[impMOTW].stats.SetStat(BASEAGI, 14);
	buffs[impMOTW].stats.SetStat(BASESTR, 14);
	
	buffs[BOK].type = PASSIVE;
	buffs[BOK].stats.SetModifier(STATMOD, 1.10);
	
	buffs[HP].type = PASSIVE;
	buffs[HP].stats.SetStat(HITPERCENT, 0.01);
	
	buffs[SUNDER].type = PASSIVE;
	buffs[SUNDER].stats.SetModifier(ARPENMOD, 0.80);
	
	buffs[HOC].type = PASSIVE;
	buffs[HOC].stats.SetStat(CRITPERCENT, 0.03);
	
	buffs[BF].type = PASSIVE;
	buffs[BF].stats.SetModifier(DAMAGEMOD, 1.04);
	
	buffs[HEROISM].type = USE;
	buffs[HEROISM].stats.SetModifier(HASTEMOD, 1.30);
	buffs[HEROISM].duration = 40 * PRECISION;
	buffs[HEROISM].cooldown = 300 * PRECISION;
	
	buffs[BERSERK_B].type = USE;
	buffs[BERSERK_B].cooldown = 180 * PRECISION;
	buffs[BERSERK_B].duration = 15 * PRECISION;
	
	if(talents.berserk)
		buffs[BERSERK_B].enabled = 1;
	
	buffs[MANGLEIDOL].type = USE;
	buffs[MANGLEIDOL].duration = 12 * PRECISION;
	buffs[MANGLEIDOL].stats.SetStat(BASEAGI, 153);
	buffs[MANGLEIDOL].enabled = 1;
	
	buffs[MUTILATIONIDOL].type = PROC;
	buffs[MUTILATIONIDOL].duration = 16 * PRECISION;
	buffs[MUTILATIONIDOL].stats.SetStat(BASEAGI, 200);
	buffs[MUTILATIONIDOL].enabled = 1;
	
	// Adds the stats of a naked, untalented, unbuffed character
	if(race == ELF)
	{
		double baseStatsArray[] = { 0, 0, 0, 86, 87, 140, 0.07476003 };
		Stats baseStats(baseStatsArray, NULL, 7, 0, baseMissChance, baseDodgeChance, baseAttackSpeed);
		staticStats += baseStats;
	}
	else
	{
		double baseStatsArray[] = { 0, 0, 0, 95, 75, 140, 0.07476003 };
		Stats baseStats(baseStatsArray, NULL, 7, 0, baseMissChance, baseDodgeChance, baseAttackSpeed);
		staticStats += baseStats;
	}
	
	staticStats.SetModifier(STATMOD, (1.0 + talents.survivalOfTheFittest * 2 / 100.0) * (1.0 + talents.improvedMarkOfTheWild / 100.0));
	staticStats.SetModifier(APMOD, 1.0 + talents.heartOfTheWild * 2 / 100.0);
	staticStats.SetModifier(DAMAGEMOD, 1 + talents.naturalist * 2 / 100.0);
	
	staticStats.AddStat(BASEAGI, agiOffset);
	staticStats.AddStat(BASESTR, strOffset);
	staticStats.AddStat(WEAPONAP, weaponAPOffset);
	staticStats.AddStat(BASEAP, apOffset + (80 * 0.5 * talents.predatoryStrikes + .066666666 * staticStats.GetStat(WEAPONAP) * talents.predatoryStrikes));
	staticStats.AddStat(CRITRATING, critOffset);
	staticStats.AddStat(HITRATING, hitOffset);
	staticStats.AddStat(ARPENRATING, arPenOffset);
	staticStats.AddStat(HASTERATING, hasteOffset);
	
	for(int i = 0; i < numBuffs; i++)
		if(buffs[i].enabled && buffs[i].type == PASSIVE)
			staticStats += buffs[i].stats;
	
	staticStats.AddStat(CRITPERCENT, talents.sharpenedClaws * 0.02 + talents.leaderOfThePack * 0.05 + talents.masterShapeshifter * 0.02 - bossCritReduction);
	staticStats.AddStat(EXPERTISEPERCENT, 0.0125 * talents.primalPrecision);
	
	critMod = 2 * (1 + talents.predatoryInstincts * (10.0/3.0) / 100) * (1 + REDMeta * 0.03);
}

void LoadSettings()
{
	ifstream iFile(configName, ios::in);
	char trinket1[100] = "";
	char trinket2[100] = "";
	char weaponEnchant[100] = "";
	int statValue = 0;
	char dummy[100];
	double tempLatency = 0;
	
	if(!iFile)
	{
		cerr << "Can't open " << configName << ", using defaults" << endl;
		
		buffs[TRINKET1] = GetProc("GrimToll", buffs[TRINKET1]);
		buffs[TRINKET2] = GetProc("Greatness", buffs[TRINKET2]);
		buffs[WEAPONENCHANT] = GetProc("Berserking", buffs[WEAPONENCHANT]);
	}
	else
	{
		int hasteRating = 0;
		int arPenRating = 0;
		int hitRating = 0;
		int expertiseRating = 0;
		int critRating = 0;
		int ap = 0;
		int weaponAP = 0;
		int agi = 0;
		int str = 0;
		int baseBossArmor = 0;
		
		iFile >> dummy >> tempLatency;
		iFile >> dummy >> fightLength;
		iFile >> dummy >> numFights;
		iFile >> dummy >> mangleBot;
		iFile >> dummy >> bleedBot;
		iFile >> dummy >> useShred;
		iFile >> dummy >> minRoarPoints;
		iFile >> dummy >> maxRoarClip;
		iFile >> dummy >> baseBossArmor;
		iFile >> dummy >> trinket1Delay;
		iFile >> dummy >> trinket2Delay;
		
		iFile >> dummy >> hasteRating;
		iFile >> dummy >> arPenRating;
		iFile >> dummy >> hitRating;
		iFile >> dummy >> expertiseRating;
		iFile >> dummy >> critRating;
		iFile >> dummy >> ap;
		iFile >> dummy >> weaponAP;
		iFile >> dummy >> agi;
		iFile >> dummy >> str;
		iFile >> dummy >> race;
		iFile >> dummy >> REDMeta;
		iFile >> dummy >> ripGlyph;
		iFile >> dummy >> shredGlyph;
		iFile >> dummy >> roarGlyph;
		iFile >> dummy >> mangleGlyph;
		iFile >> dummy >> twoT7;
		iFile >> dummy >> fourT7;
		iFile >> dummy >> twoT8;
		iFile >> dummy >> fourT8;
		iFile >> dummy >> twoT9;
		iFile >> dummy >> fourT9;
		iFile >> dummy >> ripIdol;
		iFile >> dummy >> shredIdol;
		iFile >> dummy >> mangleIdol;
		iFile >> dummy >> mutilationIdol;
		iFile >> dummy >> trinket1;
		iFile >> dummy >> trinket2;
		iFile >> dummy >> weaponEnchant;
		
		iFile >> dummy >> buffs[SOE].enabled;
		iFile >> dummy >> buffs[impSOE].enabled;
		iFile >> dummy >> buffs[BOM].enabled;
		iFile >> dummy >> buffs[impBOM].enabled;
		iFile >> dummy >> buffs[TRUESHOT].enabled;
		iFile >> dummy >> buffs[FI].enabled;
		iFile >> dummy >> buffs[SR].enabled;
		iFile >> dummy >> buffs[WF].enabled;
		iFile >> dummy >> buffs[impWF].enabled;
		iFile >> dummy >> buffs[MOTW].enabled;
		iFile >> dummy >> buffs[impMOTW].enabled;
		iFile >> dummy >> buffs[BOK].enabled;
		iFile >> dummy >> buffs[HP].enabled;
		iFile >> dummy >> buffs[SUNDER].enabled;
		iFile >> dummy >> buffs[FFF_B].enabled;
		iFile >> dummy >> buffs[HOC].enabled;
		iFile >> dummy >> buffs[BF].enabled;
		iFile >> dummy >> buffs[HEROISM].enabled;
		
		iFile >> dummy >> talents.ferocity;
		iFile >> dummy >> talents.feralAggression;
		iFile >> dummy >> talents.savageFury;
		iFile >> dummy >> talents.feralInstinct;
		iFile >> dummy >> talents.sharpenedClaws;
		iFile >> dummy >> talents.primalFury;
		iFile >> dummy >> talents.primalPrecision;
		iFile >> dummy >> talents.predatoryStrikes;
		iFile >> dummy >> talents.shreddingAttacks;
		iFile >> dummy >> talents.survivalOfTheFittest;
		iFile >> dummy >> talents.heartOfTheWild;
		iFile >> dummy >> talents.leaderOfThePack;
		iFile >> dummy >> talents.predatoryInstincts;
		iFile >> dummy >> talents.mangle;
		iFile >> dummy >> talents.improvedMangle;
		iFile >> dummy >> talents.kingOfTheJungle;
		iFile >> dummy >> talents.rendAndTear;
		iFile >> dummy >> talents.primalGore;
		iFile >> dummy >> talents.berserk;
		iFile >> dummy >> talents.improvedMarkOfTheWild;
		iFile >> dummy >> talents.naturalist;
		iFile >> dummy >> talents.omenOfClarity;
		iFile >> dummy >> talents.masterShapeshifter;
		
		latency = tempLatency * PRECISION;
		fightLength *= PRECISION;
		maxRoarClip *= PRECISION;
		trinket1Delay *= PRECISION;
		trinket2Delay *= PRECISION;
		
		staticStats.SetStat(HASTERATING, hasteRating);
		staticStats.SetStat(ARPENRATING, arPenRating);
		staticStats.SetStat(HITRATING, hitRating);
		staticStats.SetStat(EXPERTISERATING, expertiseRating);
		staticStats.SetStat(CRITRATING, critRating);
		staticStats.SetStat(BASEAP, ap);
		staticStats.SetStat(WEAPONAP, weaponAP);
		staticStats.SetStat(BASEAGI, agi);
		staticStats.SetStat(BASESTR, str);
		staticStats.SetBaseBossArmor(baseBossArmor);
		
		buffs[TRINKET1] = GetProc(trinket1, buffs[TRINKET1]);
		buffs[TRINKET2] = GetProc(trinket2, buffs[TRINKET2]);
		buffs[WEAPONENCHANT] = GetProc(weaponEnchant, buffs[WEAPONENCHANT]);
	}
	
	iFile.close();
}

Buff GetProc(const char procName[100], Buff tempBuff)
{
	if(!strcmp(procName, "GrimToll"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(ARPENRATING, 612);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .15;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 45 * PRECISION;
	}
	else if(!strcmp(procName, "BloodOfTheOldGod"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAP, 1284);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .10;
		tempBuff.trigger = CRIT;
		tempBuff.cooldown = 50 * PRECISION;
	}
	else if(!strcmp(procName, "Greatness"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(HIGHESTSTAT, 300);
		tempBuff.duration = 15 * PRECISION;
		tempBuff.procChance = .33;
		tempBuff.trigger = DAMAGE;
		tempBuff.cooldown = 45 * PRECISION;
	}
	else if(!strcmp(procName, "MjolnirRunestone"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(ARPENRATING, 665);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .15;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 45 * PRECISION;
	}
	else if(!strcmp(procName, "Berserking"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAP, 400);
		tempBuff.duration = 15 * PRECISION;
		tempBuff.procChance = 1.2 / 60;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 0;
	}
	else if(!strcmp(procName, "Mongoose"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAGI, 120);
		tempBuff.stats.SetModifier(HASTEMOD, 1.02);
		tempBuff.duration = 15 * PRECISION;
		tempBuff.procChance = 1.0 / 60;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 0;
	}
	else if(!strcmp(procName, "Executioner"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(ARPENRATING, 120);
		tempBuff.duration = 15 * PRECISION;
		tempBuff.procChance = 1.0 / 60;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 0;
	}
	else if(!strcmp(procName, "CometsTrail"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(HASTERATING, 726);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .15;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 45 * PRECISION;
	}
	else if(!strcmp(procName, "Wrathstone"))
	{
		tempBuff.type = USE;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAP, 856);
		tempBuff.duration = 20 * PRECISION;
		tempBuff.cooldown = 120 * PRECISION;
	}
	else if(!strcmp(procName, "PyriteInfuser"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAP, 1234);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .10;
		tempBuff.trigger = CRIT;
		tempBuff.cooldown = 50 * PRECISION;
	}
	else if(!strcmp(procName, "MirrorOfTruth") || !strcmp(procName, "AnvilOfTitans"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAP, 1000);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .10;
		tempBuff.trigger = CRIT;
		tempBuff.cooldown = 50 * PRECISION;
	}
	else if(!strcmp(procName, "MeteoriteWhetstone"))
	{
		tempBuff.type = PROC;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(HASTERATING, 444);
		tempBuff.duration = 10 * PRECISION;
		tempBuff.procChance = .15;
		tempBuff.trigger = HIT;
		tempBuff.cooldown = 45 * PRECISION;
	}
	else if(!strcmp(procName, "MarkOfNorgannon"))
	{
		tempBuff.type = USE;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(HASTERATING, 491);
		tempBuff.duration = 20 * PRECISION;
		tempBuff.cooldown = 120 * PRECISION;
	}
	else if(!strcmp(procName, "LoathebsShadow") || !strcmp(procName, "SphereOfRedDragonsBlood"))
	{
		tempBuff.type = USE;
		tempBuff.enabled = 1;
		tempBuff.stats.SetStat(BASEAP, 670);
		tempBuff.duration = 20 * PRECISION;
		tempBuff.cooldown = 120 * PRECISION;
	}
	else if(strcmp(procName, "None"))
	{
		cerr << "Unsupported proc: " << procName << endl;
	}
	
	return tempBuff;
}